﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using Ignitron.EEngine;
using Ignitron.EEngine.Maths;
using Ignitron.EEngine.Lighting;

namespace OpenTKLightingTool.Data
{
    /// <summary>
    /// Data class representing a light
    /// </summary>
    internal class Light
    {
        /// <summary>
        /// Flag for enabling the light
        /// </summary>
        public bool IsEnabled
        { get; set; }

        /// <summary>
        /// Light's position or direction
        /// </summary>
        public EVector4 Position
        { get; set; }

        /// <summary>
        /// Light color components
        /// </summary>
        public EVector4 Ambient
        { get; set; }

        public EVector4 Diffuse
        { get; set; }

        public EVector4 Specular
        { get; set; }

        
        /// <summary>
        /// Light attenuation coefficients
        /// </summary>
        public float ConstantAttenuation
        { get; set; }

        public float LinearAttenuation
        { get; set; }

        public float QuadraticAttenuation
        { get; set; }


        /// <summary>
        /// Spot light parameters
        /// </summary>
        public float SpotCutOff
        { get; set; }

        public EVector4 SpotDirection
        { get; set; }

        public float SpotExponent
        { get; set; }

        /// <summary>
        /// Ignitron Engine light
        /// </summary>
        private ELight mLight;

        /// <summary>
        /// Constructor - set default values
        /// </summary>
        public Light(IEngine engine, ELight eLight = null)
        {
            IsEnabled = false;

            Position = new EVector4(0, 0, 0, 1);

            Ambient = new EVector4(0, 0, 0, 1);
            Diffuse = new EVector4(0, 0, 0, 1);
            Specular = new EVector4(0, 0, 0, 1);

            ConstantAttenuation = 1f;
            LinearAttenuation = 0f;
            QuadraticAttenuation = 0f;

            SpotCutOff = 180f;
            SpotDirection = new EVector4(0, 0, 0, 1);
            SpotExponent = 0f;

            if (eLight == null)
            {
                mLight = engine.CreateLight();
            }
            else
            {
                mLight = eLight;
            }

            UpdateELight();
        }

        public ELight ELight
        {
            get { return mLight; }
        }

        public void UpdateELight()
        {
            mLight.IsTurnedOn = IsEnabled;
            mLight.Ambient = Ambient;
            mLight.Diffuse = Diffuse;
            mLight.Specular = Specular;
            mLight.ConstantAttenuation = ConstantAttenuation;
            mLight.LinearAttenuation = LinearAttenuation;
            mLight.QuadraticAttenuation = QuadraticAttenuation;
            mLight.Position = Position;
        }

        /// <summary>
        /// Renders the light
        /// </summary>
        public void Render(IEngine engine)
        {
            UpdateELight();
            
            engine.RenderLight(mLight);
        }

        /// <summary>
        /// Renders the light cross at its position
        /// </summary>
        public void RenderLightCross(IEngine engine)
        {
            float halfSize = 0.1f;

            engine.EnableLighting(false);

            engine.BeginLines();

            engine.RenderLine(new EVector3(Position.X - halfSize, Position.Y, Position.Z), new EVector3(Position.X + halfSize, Position.Y, Position.Z), new EVector4(1, 0, 1, 1));
            engine.RenderLine(new EVector3(Position.X, Position.Y - halfSize, Position.Z), new EVector3(Position.X, Position.Y + halfSize, Position.Z), new EVector4(1, 0, 1, 1));
            engine.RenderLine(new EVector3(Position.X, Position.Y, Position.Z - halfSize), new EVector3(Position.X, Position.Y, Position.Z + halfSize), new EVector4(1, 0, 1, 1));

            engine.EndLines();

            engine.EnableLighting(true);
        }
    }
}
